package org.project2.myJunitTeacher.framework;

import org.project2.myJunitTeacher.annotations.*;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class MyJunitRunner {
    public static void run(Class cls){
        //反射执行
        List<Method> beforeClassMethods = new ArrayList<>();
        List<Method> afterClassMethods = new ArrayList<>();
        List<Method> beforeMethods = new ArrayList<>();
        List<Method> afterMethods = new ArrayList<>();
        List<Method> ignoreMethods = new ArrayList<>();
        List<Method> testMethods = new ArrayList<>();

        //1.取出cls中的方法
        Method[] methods = cls.getMethods();
        for (Method method : methods) {
            Annotation[] an = method.getAnnotations();
            for (Annotation annotation : an) {
                if (annotation instanceof MyBeforeClass){
                    beforeClassMethods.add(method);
                }
                if (annotation instanceof MyBefore){
                    beforeMethods.add(method);
                }
                if (annotation instanceof MyAfter){
                    afterMethods.add(method);
                }
                if (annotation instanceof MyAfterClass){
                    afterClassMethods.add(method);
                }
                if (annotation instanceof MyIgnore){
                    ignoreMethods.add(method);
                }
                if (annotation instanceof MyTest){
                    testMethods.add(method);
                }
            }
        }

        try{
            for (Method beforeClassMethod : beforeClassMethods) {
                beforeClassMethod.invoke(null);
            }

            for (Method testMethod : testMethods) {
                Object obj=cls.newInstance();
                for (Method beforeMethod : beforeMethods) {
                    beforeMethod.invoke(obj);
                }
                testMethod.invoke(obj);
                for (Method afterMethod : afterMethods) {
                    afterMethod.invoke(obj);
                }
            }
            for (Method afterClassMethod : afterClassMethods) {
                afterClassMethod.invoke(null);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
